﻿// --- Copyright (c) 2006-2008 Stefan Kyntchev ---
// This software is written and copyrighted by Stefan Kyntchev 
// and BeyondPod Team members. All rights are reserved.
// Author contact: support@beyondpod.mobi
// ------------------------------------------------------------------------
// This file is part of BeyondPod RSS Feed Reader and Podcast manager
// (www.codeplex.com/BeyondPod) 
// BeyondPod is free software: you can redistribute it and/or modify 
// it under the terms of the GNU General Public License as published by 
// the Free Software Foundation, either version 3 of the License, or 
// (at your option) any later version. 
//  
// BeyondPod is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
// GNU General Public License for more details. 
//  
// You should have received a copy of the GNU General Public License
// along with BeyondPod. If not, see <http://www.gnu.org/licenses/>
// ------------------------------------------------------------------------
// COPYRIGHT NOTICE: This copyright notice may NOT be removed, obscured or modified 
// without written consent from the author.
// --- End copyright notice --- 


using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;

namespace svs.Mobile.BeyondMedia.FeedCore.Helpers
{
	public class FlashStorageLocation
	{
		private static string DeviceRoot = @"\";
		private long m_AvailableSpace;
		private string m_Path;
		private long m_TotalSpace;

		public FlashStorageLocation(string path)
		{
			m_Path = path;
			RefreshLocation();
		}

		public string Path
		{
			get { return m_Path; }
			set { m_Path = value; }
		}

		public long		AvailableSpace
		{
			get { return m_AvailableSpace; }
			set { m_AvailableSpace = value; }
		}

		public string AvailableSpaceAsString
		{
			get
			{
				return CoreHelper.GetFileLengthAsString(AvailableSpace);
			}
		}

		public string TotalSpaceAsString
		{
			get
			{
				return CoreHelper.GetFileLengthAsString(TotalSpace);
			}
		}

		public long TotalSpace
		{
			get { return m_TotalSpace; }
			set { m_TotalSpace = value; }
		}

		public string FriendlyLocationName
		{
			get
			{
				string path = m_Path.TrimStart( new char[]{'\\'});
				return path.Length == 0?"Main Storage":path;
			}
		}

		public override string ToString()
		{
			return FriendlyLocationName;
		}

		[DllImport("coredll.dll")]
		private static extern
			bool GetDiskFreeSpaceEx(
			string directoryName,
			out ulong FreeBytesAvailableToCaller,
			out ulong TotalNumberOfBytes,
			out ulong TotalNumberOfFreeBytes
			);

		public void RefreshLocation()
		{
			ulong freeBytesForCaller = 0;
			ulong totalBytes = 0;
			ulong totalFreeBytes = 0;

			try
			{
				bool success = GetDiskFreeSpaceEx(m_Path, out freeBytesForCaller, out totalBytes, out totalFreeBytes);
				m_AvailableSpace = success ? (long)freeBytesForCaller : -1;
				m_TotalSpace = success ? (long)totalBytes : -1;
			}
			catch
			{
				//On teh desktop GetDiskFreeSpaceEx throws an exception
				m_TotalSpace = m_AvailableSpace = 300*1024;
			}
		}

		public bool CheckIfSpaceIsAvailable(long needed)
		{
			return AvailableSpace > needed;
		}

		public static List<FlashStorageLocation> GetAvailableStorageLocations()
		{
			List<FlashStorageLocation> retVal = new List<FlashStorageLocation>(2);
			retVal.Add(new FlashStorageLocation(DeviceRoot));

			DirectoryInfo root = new DirectoryInfo(DeviceRoot);

			foreach (DirectoryInfo directory in root.GetDirectories("*"))
			{
				if ((directory.Attributes & FileAttributes.Temporary) == FileAttributes.Temporary)
				{
					FlashStorageLocation l = new FlashStorageLocation(directory.FullName);
					if (l.TotalSpace > 0)
						retVal.Add(l);
				}
			}

			return retVal;
		}

		public static bool CheckIfSpaceIsAvailable(string Path, long needed)
		{
			FlashStorageLocation l = new FlashStorageLocation(Path);
			return l.CheckIfSpaceIsAvailable(needed);
		}

		public static long? GetFreeSpaceAtFeedDownloadPath(Feed feed)
		{
			string downloadPath = string.IsNullOrEmpty(feed.FeedPath) ? Configuration.EnclosureDownloadPath : feed.FeedPath;
			var loc = new FlashStorageLocation(downloadPath);
			return loc.TotalSpace > 0 ? (long?)loc.AvailableSpace : null;
		}
	}
}